package com.auxgroup.hr.front.site.co.process;

import java.util.*;

import javax.annotation.Resource;

import com.auxgroup.hr.front.site.co.BaseWfCO;
import com.auxgroup.hr.front.site.inteceptor.SessionGain;
import com.auxgroup.hr.front.site.vo.process.EmplAbsentRespVO;
import com.auxgroup.hr.front.site.vo.process.WfCrdDtlRespVO;
import com.auxgroup.hr.front.site.vo.process.WfCrdHdrRespVO;
import com.auxgroup.hr.front.site.vo.process.WfCrdSaveReqVO;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSONArray;
import com.auxgroup.hr.front.commons.BaseRetCode;
import com.auxgroup.hr.front.commons.enums.WfActionTypeEnum;
import com.auxgroup.hr.front.commons.enums.WfStatusEnum;
import com.auxgroup.hr.front.commons.enums.WfTypeEnum;
import com.auxgroup.hr.front.commons.utils.DateUtils;
import com.auxgroup.hr.front.commons.vo.BaseResponseVO;
import com.auxgroup.hr.front.commons.vo.UserDTO;
import com.auxgroup.hr.front.dao.domain.PsCAppStepInst;
import com.auxgroup.hr.front.dao.domain.PsCEmpAbsentVw;
import com.auxgroup.hr.front.dao.domain.PsCEmplCrdDVw;
import com.auxgroup.hr.front.dao.domain.PsCWfCrdDtl;
import com.auxgroup.hr.front.dao.domain.PsCWfCrdHdr;
import com.auxgroup.hr.front.dozer.IObjectMapper;
import com.auxgroup.hr.front.service.comm.SysDictService;
import com.auxgroup.hr.front.service.process.ProcessService;
import com.auxgroup.hr.front.service.process.WfCrdHdrService;
import com.auxgroup.hr.front.service.process.WfFileService;
import com.auxgroup.hr.front.site.co.BaseCO;
import com.auxgroup.hr.front.site.inteceptor.SessionGain;
import com.auxgroup.hr.front.site.vo.process.EmplAbsentRespVO;
import com.auxgroup.hr.front.site.vo.process.WfCrdDtlRespVO;
import com.auxgroup.hr.front.site.vo.process.WfCrdHdrRespVO;
import com.auxgroup.hr.front.site.vo.process.WfCrdSaveReqVO;
import com.auxgroup.hr.front.ws.ProcessApplyQueDTO;

/**
 * 补卡申请审批
 * @author lv-PC
 *
 */
@RestController
@RequestMapping("${auxgroup.hr.contextPath}/wfCrdHdr")
public class WfCrdHdrCO extends BaseWfCO {

	private static final Logger logger = LoggerFactory.getLogger(WfCrdHdrCO.class);

	@Autowired
	private WfCrdHdrService wfCrdHdrService;

	@Resource(name = "dozerMapper")
	protected IObjectMapper objectMapper;
	
	/**
	 * 获取补卡申请信息
	 * @param hireId
	 * @return
	 */
	@GetMapping(value = "/getCrdInfo")
	public BaseResponseVO getOne(String cTransactionNbr,@SessionGain("user") UserDTO user) {
		logger.info("getCrdInfo param= {}", cTransactionNbr);
		if(StringUtils.isBlank(cTransactionNbr)){
			return buildRespone(BaseRetCode.CODE_ERROR_REQUEST_PARAM_NULL);
		}
		PsCWfCrdHdr crdHdr = wfCrdHdrService.getWfCrdHdr(cTransactionNbr);
		if(crdHdr==null){
			return buildRespone(BaseRetCode.CODE_ERROR_PROCESS_NOT_EXIST);
		}
		WfCrdHdrRespVO respVo = objectMapper.map(crdHdr, WfCrdHdrRespVO.class);
		
		List<PsCWfCrdDtl> dtls = wfCrdHdrService.getWfCrdDtl(cTransactionNbr);
		buildCrdDtlResp(respVo,dtls);
		respVo.setCrdComment(crdHdr.getcOtherExplain());//补卡事由
		fillBaseWfInfo(user, crdHdr, respVo);
		return buildRespone(respVo);
	}
	
	/**
	 * 构建返回明细
	 * @param respVo
	 * @param dtls
	 */
	private void buildCrdDtlResp(WfCrdHdrRespVO respVo,List<PsCWfCrdDtl> dtls){
		if(dtls==null||dtls.isEmpty()){
			return;
		}
		List<WfCrdDtlRespVO> dtlVos = new ArrayList<WfCrdDtlRespVO>();
		WfCrdDtlRespVO dtlvo;
		for (PsCWfCrdDtl dtl : dtls) {
			dtlvo = new WfCrdDtlRespVO();
			dtlvo.setCrdDate(DateUtils.format(dtl.getDateDay(), DateUtils.FORMAT_DEFAULT));
			dtlvo.setCrdReason(dtl.getcPatchReason());
			dtlvo.setCrdTime(dtl.getcLeaveInterval());
			dtlVos.add(dtlvo);
		}
		respVo.setCrdJson(dtlVos);
	}
	
	
	/**
	 * 保存补卡申请流程
	 * @return
	 */
	@PostMapping(value="/saveWfCrd")
	public BaseResponseVO saveWfCrd(String cTransactionNbr, WfCrdSaveReqVO reqVo, @SessionGain("user") UserDTO user){
		logger.info("saveWfCrd param:{},leaveInfo:{},transNum:{}",reqVo);
        if(reqVo==null){
        	return buildRespone(BaseRetCode.CODE_ERROR_REQUEST_PARAM_NULL.getRetCode(),"保存入参不能为空");
        }
        if(StringUtils.isBlank(cTransactionNbr)){
        	cTransactionNbr = processService.getTranNum();
        	if(StringUtils.isBlank(cTransactionNbr)){
        		return buildRespone(BaseRetCode.CODE_ERROR_GET_TRANSACTION_NBR_FAILED);
        	}
        }
        //构建明细数据
        List<PsCWfCrdDtl> dtls = buildCrdDtls(reqVo, user.getEmplId());
        //保存补卡申请
        PsCWfCrdHdr crdHdr = wfCrdHdrService.saveWfCrdHdr(cTransactionNbr, user, dtls,reqVo.getCrdComment());
        if(crdHdr!=null){
        	ProcessApplyQueDTO requestDTO = new ProcessApplyQueDTO();
        	if(WfStatusEnum.WF_STATUS_S.getStatus().equals(crdHdr.getcWfStatus())){
        		requestDTO.setC_ACTION_TYPE(WfActionTypeEnum.WF_ACTION_SUBMIT.getAction());
        	}else{
        		requestDTO.setC_ACTION_TYPE(WfActionTypeEnum.WF_ACTION_RESUBMIT.getAction());
        	}
            requestDTO.setC_TRANSACTION_NBR(cTransactionNbr);
            requestDTO.setC_USERID(user.getOprId());
            requestDTO.setC_WF_TYPE(WfTypeEnum.WF_STYPE_CRD.getType());
            Map<String, String> approveResult = processService.apply(requestDTO);
            if(approveResult==null||approveResult.isEmpty()){
    			return buildRespone(BaseRetCode.CODE_ERROR_PROCESS_APPLY_FAIL);
    		}
            if("0".equals(approveResult.get("C_MSG_CODE"))){
            	return buildRespone(cTransactionNbr);
            }else{
            	//只有初次发起时，发起失败才删除数据
            	if(WfStatusEnum.WF_STATUS_S.getStatus().equals(crdHdr.getcWfStatus())){
            		//流程发起失败，删除数据
                	wfCrdHdrService.delCrdHdr(cTransactionNbr);
            	}
            	return buildRespone(approveResult.get("C_MSG_CODE"), approveResult.get("C_MSG_TEXT"));
            }
        }else{
        	return buildRespone(BaseRetCode.CODE_ERROR_PROCESS_APPLY_FAIL);
        }
	}
	
	/**
	 * 构建明细集合
	 * @param crdJson
	 * @return
	 */
	private List<PsCWfCrdDtl> buildCrdDtls(WfCrdSaveReqVO reqVo,String emplid){
		List<PsCWfCrdDtl> dtls = new ArrayList<PsCWfCrdDtl>();
		PsCWfCrdDtl dtl;
		if(StringUtils.isNotBlank(reqVo.getCrdJson())){
			JSONArray reqs = JSONArray.parseArray(reqVo.getCrdJson());
			for (int i = 0; i < reqs.size(); i++) {
				WfCrdDtlRespVO dtlVo = reqs.getObject(i, WfCrdDtlRespVO.class);
				dtl = new PsCWfCrdDtl();
				dtl.setEmplid(emplid);
			    dtl.setcPatchReason(dtlVo.getCrdReason());
			    dtl.setcLeaveInterval(dtlVo.getCrdTime());
			    dtl.setDateDay(DateUtils.parseDate(dtlVo.getCrdDate(), DateUtils.FORMAT_DEFAULT));
			    dtls.add(dtl);
			}
		}else{
			dtl = new PsCWfCrdDtl();
			dtl.setEmplid(emplid);
		    dtl.setcPatchReason(reqVo.getCrdReason());
		    dtl.setcLeaveInterval(reqVo.getCrdTime());
		    dtl.setDateDay(DateUtils.parseDate(reqVo.getCrdDate(), DateUtils.FORMAT_DEFAULT));
		    dtls.add(dtl);
		}
		return dtls;
	}
	
	
	
	
	/**
	 * 获取异常旷工记录
	 * @param user
	 * @return
	 */
	@GetMapping(value = "/getabsents")
	public BaseResponseVO getEmplAbsentInfo(String emplid, @SessionGain("user") UserDTO user){
		logger.info("get absents start");
		if(emplid==null){
			emplid = user.getEmplId();
		}
		List<PsCEmpAbsentVw> absents = wfCrdHdrService.getAbsents(emplid);
		if(absents==null||absents.isEmpty()){
			return buildRespone(Collections.EMPTY_LIST);
		}
		List<EmplAbsentRespVO> respVos = new ArrayList<EmplAbsentRespVO>();
		List<PsCEmplCrdDVw> crds = wfCrdHdrService.getCrds(emplid);
		EmplAbsentRespVO respVo;
		List<Map<String, String>> signList;
		Map<String, String> sign;
		for (PsCEmpAbsentVw absent : absents) {
			respVo = new EmplAbsentRespVO();
			respVo.setEmplid(absent.getEmplid());
			respVo.setUnusualType("旷工");
			respVo.setDateDay(DateUtils.format(absent.getDateDay(), DateUtils.FORMAT_DEFAULT));
			signList = new ArrayList<Map<String,String>>();
			for (PsCEmplCrdDVw crd : crds) {
				if(absent.getDateDay().equals(crd.getDateDay())){
					sign = new HashMap<String, String>();
					sign.put("signTime", DateUtils.format(crd.getcCardTime(), DateUtils.FORMAT_YYYYMMDDHHMISS));
					signList.add(sign);
				}
			}
			respVo.setSignList(signList);
			respVos.add(respVo);
		}
		return buildRespone(respVos,false);
	}


	@Override
	protected Set<String> getAuthFileds() {
		return null;
	}
}
